package com.javakc.platform.modules.system.logger.component.advice;

import com.javakc.platform.modules.system.logger.component.annotation.LoggerOperation;
import com.javakc.platform.modules.system.logger.dao.LoggerDao;
import com.javakc.platform.modules.system.logger.entity.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author zhouhonggang
 * @version 1.0.0
 * @project springboot-development-platform
 * @datetime 2022-04-13 10:50
 * @description: [系统管理·日志通知]
 */
@Aspect
@Component
public class LoggerAdvice {

    @Autowired
    private LoggerDao loggerDao;

    /**
     * 切入点  LoggerOperation
     */
    @Pointcut("@annotation(com.javakc.platform.modules.system.logger.component.annotation.LoggerOperation)")
    public void pointcut(){}

    /**
     * AOP拦截日志功能
     * @param joinPoint 连接点
     * @return  返回结果
     * @throws Throwable 异常
     */
    @Around("pointcut()")
    public Object logger(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object object = joinPoint.proceed();
        long end = System.currentTimeMillis();
        //获取注解类
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        LoggerOperation annotation = signature.getMethod().getAnnotation(LoggerOperation.class);
        logger(end-start, annotation.module(), annotation.type().getValue(), annotation.message());
        return object;
    }

    /**
     * 日志提那家
     * @param times     耗时
     * @param module    模块
     * @param type      类型
     * @param message   消息
     */
    public void logger(long times, String module, String type, String message)
    {
        //获取请求对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();

        Logger entity = new Logger();
        entity.setModule(module);
        entity.setType(type);
        entity.setMessage(message);
        entity.setRequestMethod(request.getMethod());
        entity.setRequestIpaddr(request.getRemoteAddr());
        entity.setRequestUrl(request.getRequestURL().toString());
        entity.setExecuteTime(times);
        loggerDao.insert(entity);
    }

}
